Conversation
|
Какой знакомый код. А Елена Смирнова точно дала своё согласие на его заимствование? |
| public double calculate(String Expression) throws ParsingException { | ||
| if (!isExpressionCorrect(Expression)) { | ||
| throw new ParsingException("Invalid expression"); | ||
| private String whatIsIt(Character Symbol) { |
There was a problem hiding this comment.
"Ochen` ploxo", ochen'
Неужели нельзя это не так по-индуски сделать?
ignorer
left a comment
There was a problem hiding this comment.
Вынужден сообщить, что читаемость у этого кода далеко не на самом высоком уровне. Прочитав два десятка калькуляторов, я не могу понять, как работает твой, хотя идеологически он вряд ли отличается сильно. Проблема на мой взгляд в слишком больших switch блоках, злоупотреблении ими и отсутствии хоть каких-то комментариев к происходящему.
Некоторые замечания, которые я оставил к твоему коду, относятся не только к той строчке, к которой привязаны, поэтому будь добр, пройдись по всему коду и исправь ошибки в аналогичных местах.
| public double calculate(String Expression) throws ParsingException { | ||
| if (!isExpressionCorrect(Expression)) { | ||
| throw new ParsingException("Invalid expression"); | ||
| private String whatIsIt(Character symbol) { |
There was a problem hiding this comment.
Любой человек, который знает Java, понимает разницу между базовыми типами и их обёртками, а также про боксинг и анбоксинг, про который семинарист рассказывал вам ещё в начале семестра. Настоятельно рекомендую почитать материалы семинаров, документацию по java или stackoverflow.com и ознакомиться с тем, что такое primitive wrapper class, boxing и unboxing, а после этого со знанием дела объяснить, зачем тебе здесь именно Character.
| public double calculate(String Expression) throws ParsingException { | ||
| if (!isExpressionCorrect(Expression)) { | ||
| throw new ParsingException("Invalid expression"); | ||
| private String whatIsIt(Character symbol) { |
There was a problem hiding this comment.
Ты можешь представить, какой оверхед создаёт эта функция? Если Java ничего не оптимизирует, а будет под каждый вызов твоей волшебной функции whatIsIT() создавать новую строку, этот калькулятор будет съедать памяти раз в 50 больше нужного.
Теперь вопрос: а почему, собственно, возвращается строка? enum SymbolType в списанном решении был таким хорошим, а тут у тебя аж строки возвращаются. Мне кажется, что ответ - чтобы код не был похож на предыдущее решение, но это не точно.
| case '6': | ||
| case '7': | ||
| case '8': | ||
| case '9': |
There was a problem hiding this comment.
Итак, у нас есть задача - нужно определить, является ли символ цифрой. У этой, не побоюсь этого слова, задачи есть несколько решений, из которых ты выбрал самое беспонтовое. Предлагаю ознакомиться с документацией к классу Character (хотя бы пролистать список методов) и сказать, что нам предлагает сам язык в этом плане.
| } | ||
| case ' ': | ||
| case '\t': | ||
| case '\n': |
There was a problem hiding this comment.
Аналогично тому, что я писал выше про числа - для этого уже сделана стандартная функция, и тебе предлагается её отыскать.
| private enum SymbolType { | ||
| OPENING_BRACKET, CLOSING_BRACKET, NUMBER, OPERATOR, NOTHING | ||
|
|
||
| private Integer getCode(Character first, Character second) { |
There was a problem hiding this comment.
А какой именно код возвращает эта функция? Лично мне сходу вообще непонятна семантика этой функции, в которой к тому же ещё и вложенные switch блоки, а значения кодов - тайна, покрытая мраком и нигде не задокументированная.
| if (previousSymbol == SymbolType.OPENING_BRACKET || | ||
| previousSymbol == SymbolType.OPERATOR) { | ||
| return false; //открывающая-закрывающая, оператор-закрывающая | ||
| for (int cnt = 0; cnt < expression.length(); ++cnt) { |
There was a problem hiding this comment.
Название cnt по меньшей мере чрезвычайно странное. Как минимум оно трактуется неоднозначно - у тебя оно ассоциируется со словом count, у меня со словом cunt (или наоборот), а двузначность в коде - плохо. И вообще count - это количество или подсчёт, но никак не индекс (счётчик здесь тоже не подходит, ты же ничего не считаешь, а только итерируешься по строке).
И привыкай не использовать в коде сокращения имён (кроме общепринятых). Они хороши только когда пишешь код на листочке без автодополнения.
| private StringBuilder removeSpaces(String expression) { | ||
| StringBuilder result = new StringBuilder(expression.length()); | ||
| for (int cnt = 0; cnt < expression.length(); ++cnt) { | ||
| if (!whatIsIt(expression.charAt(cnt)).equals("Space")) { |
There was a problem hiding this comment.
Вот это можно вообще без whatIsIt() сделать также одной строчкой.
| expression.append('~'); | ||
| Character curSymbol; | ||
| Character prevSymbol = '~'; | ||
| Stack<Character> Texas = new Stack<>(); |
There was a problem hiding this comment.
В java code conventions явно указывается, что переменные называются с маленькой буквы.
| if (currChar == ' ' || currChar == '\n' || currChar == '\t') { | ||
| continue; | ||
| Integer cnt = 0; | ||
| while (true) { |
There was a problem hiding this comment.
Как интересно ты в исходном решении заменил for на while.
| @Override | ||
| public double calculate(String expression) throws ParsingException { | ||
| isAlmostValid(expression); | ||
| StringBuilder withoutSpaces = removeSpaces(expression); |
There was a problem hiding this comment.
А зачем тебе именно StringBuilder возвращать из функции? Ты же можешь вернуть return stringBuilder.toString(), и тогда на выходе будет строка, и тип переменной withoutSpaces будет вполне себе понятным - String. А то пока это выглядит так, как будто ты планируешь дальше строить эту строку.
| import ru.mipt.java2016.homework.base.task1.Calculator; | ||
| import ru.mipt.java2016.homework.base.task1.ParsingException; | ||
|
|
||
| import java.util.*; |
There was a problem hiding this comment.
Считается плохим тоном импортировать через *. Перечисли всё, что ты импортируешь отдельно
| import java.util.*; | ||
|
|
||
| // подробное описание работы кода | ||
| // можно найти в файле description |
There was a problem hiding this comment.
Пиши комментарии прямо в коде
| if (symbol.equals('~')) { | ||
| return SymbolType.FIRST; | ||
| } | ||
| return SymbolType.INVALID; |
There was a problem hiding this comment.
Во многих языках программирования есть такая штука, как assert. Его используют, чтобы поймать некорректные состояния. Этот твой SymbolType.INVALID - как раз такое состояние. Кидай отсюда исключение
| OPENING_BRACKET, CLOSING_BRACKET, FIRST, INVALID } | ||
|
|
||
|
|
||
| private SymbolType whatIsIt(Character symbol) { |
There was a problem hiding this comment.
Не слишком-то похоже на понятное название
Почему принимает Character?
| } | ||
|
|
||
|
|
||
| private int getCode(char first, char second) { |
There was a problem hiding this comment.
Как говорили Великие:
А какой именно код возвращает эта функция? Лично мне сходу вообще непонятна семантика этой функции, в которой к тому же ещё и вложенные switch блоки, а значения кодов - тайна, покрытая мраком и нигде не задокументированная.
Почему не сделать enum вместо цифр? С ним назначение функции слегка прояснится. Заодно можно будет переименовать getCode во что-нибудь более определенное
| Character curSymbol; | ||
| Character prevSymbol = '~'; | ||
| Stack<Character> texas = new Stack<>(); | ||
| StringBuilder california = new StringBuilder(expression.length()); |
There was a problem hiding this comment.
То, что в статье, которую ты скинул, есть слова Техас и Калифорния, ещё не значит, что их нужно использовать, как названия переменных. Придумай что-нибудь более говорящее
Second attempt:)